package com.googlecode.curvedmetromaps.core.logic.costfunction;

import org.jbox2d.common.Vec2;

import com.googlecode.curvedmetromaps.core.geometry.BasicGeometry;
import com.googlecode.curvedmetromaps.core.model.MetroLine;
import com.googlecode.curvedmetromaps.core.model.MetroMap;

public class MetroLineSmoothnessCost extends BaseCost {

	public MetroLineSmoothnessCost(MetroMap map) {
		super(map);
		createWeight("base", "Base weight", 100);
	}

	@Override
	public String getName() {
		return "Metro line smoothness";
	}

	@Override
	public double calculateCost() {
		double result = 0;
		int count = 0;

		for (MetroLine line : map.lines) {
			if (line.stations.length < 4)
				continue;

			double previousAngle = 0;
			Vec2 v0 = line.stations[0].getPosition();
			Vec2 v1 = line.stations[1].getPosition();
			Vec2 v2 = null;
			for (int i = 2; i < line.stations.length; i++) {
				v2 = line.stations[i].getPosition();
				double angle = BasicGeometry.dAngle(v0, v1, v2);

				if (i >= 3) {
					// The cost is the difference with the previous angle.
					result += Math.abs(angle - previousAngle);
					count++;
				}

				previousAngle = angle;
				v0 = v1;
				v1 = v2;
			}
		}

		// Calculate average cost.
		result /= count;
		return getWeight("base") * result;
	}
}
